Как известно,
функция Аккермана играет важную роль в теоретической информатике. Однако, с
другой стороны, её быстрый рост вызывает трудности при вычислении.
Функция
Аккермана может быть определена рекурсивно для неотрицательных целых чисел m
и n следующим образом:
По заданным m
и n вычислите значение A(m, n).
Вход. В каждой строке входных данных
находятся два неотрицательных целых числа m и n, где 0 ≤ m
≤ 3. Для всех m < 3 значение n не превышает 1000000,
если же m = 3, то значение n не превышает 24.
Выход. Для
каждой заданной пары чисел выведите в отдельной строке искомое значение функции
Аккермана A(m, n).
Пример входа |
Пример выхода |
1 3 2 4 |
5 11 |
математика
Анализ алгоритма
Если m =
0, то A(0, n) = n + 1. Что следует из условия.
Если m =
1, то A(1, n) = A(0, A(1, n – 1)) = A(1, n – 1) + 1 = A(1,
n – 2) + 2 = … = A(1, 0) + n = A(0, 1) + n = 2 + n.
Если m =
2, то A(2, n) = A(1, A(2, n – 1)) = A(2, n – 1) + 2 = A(2,
n – 2) + 4 = … = A(2, 0) + 2n
= A(1, 1) + 2n = 2 + 1 + 2n = 2n
+ 3.
Если m =
3, то A(3, n) = A(2, A(3, n – 1)) = 2 * A(3, n – 1) + 3 =
2 * (2 * A(3, n – 2) + 3) + 3 = 4 * A(3, n – 2) + 3*2 + 3 = 8 *
A(3, n – 3) + 3*4 + 3*2 + 3 = … = 2n * A(3, 0) + 3*2n–1
+ … + 3*4 + 3*2 + 3 = 2n * A(2, 1) + 3*(2n
– 1) = 2n * (2*1 + 3) + 3*2n – 3 = 2n+3
– 3.
Итак, имеем
следующий набор формул:
A(0, n)
= n + 1,
A(1, n)
= n + 2,
A(2, n)
= 2n + 3,
A(3, n)
= 2n+3 – 3
Реализация алгоритма
Читаем входные данные. В
зависимости от значения m вычисляем ответ по одной из приведенных в
анализе задачи формул.
while(scanf("%lld
%lld",&m,&n) == 2)
{
if (m == 0)
res = n + 1; else
if (m == 1)
res = n + 2; else
if (m == 2)
res = 2*n + 3; else res = (1 << (n + 3))
- 3;
printf("%lld\n",res);
}
Java реализация
import java.util.*;
public class Main
{
public static void main(String[] args)
{
Scanner con = new Scanner(System.in);
long res;
while(con.hasNextLong())
{
long m = con.nextLong();
long n = con.nextLong();
if (m == 0) res = n + 1; else
if (m == 1) res = n + 2; else
if (m == 2) res = 2*n + 3; else
res = (1 << (n + 3)) - 3;
System.out.println(res);
}
con.close();
}
}